package io.kiki.sba.registry.common.model;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.kiki.sba.registry.common.model.constants.ValueConstants;
import io.kiki.sba.registry.common.model.store.Url;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.net.InetSocketAddress;
import java.util.Objects;

/**
 * client to clientInterface server node info
 */
@Setter
@Getter
public final class ClientToClientInterfaceServerNodeId implements Serializable {
    @Getter
    private final String clientIp;
    @Getter
    private final int clientPort;
    @Getter
    private final String serverIp;
    @Getter
    private final int serverPort;
    private int hash;

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public ClientToClientInterfaceServerNodeId(@JsonProperty("clientIp") String clientIp, @JsonProperty("clientPort") int clientPort, @JsonProperty("serverIp") String serverIp, @JsonProperty("serverPort") int serverPort) {
        this.clientIp = clientIp;
        this.clientPort = clientPort;
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }

    public static ClientToClientInterfaceServerNodeId of(String clientAddress, String serverAddress) {
        Url clientUrl = Url.valueOf(clientAddress);
        Url serverUrl = Url.valueOf(serverAddress);
        return new ClientToClientInterfaceServerNodeId(clientUrl.getIp(), clientUrl.getPort(), serverUrl.getIp(), serverUrl.getPort());
    }

    public static ClientToClientInterfaceServerNodeId of(InetSocketAddress clientAddress, InetSocketAddress serverAddress) {
        return new ClientToClientInterfaceServerNodeId(clientAddress.getAddress().getHostAddress(), clientAddress.getPort(), serverAddress.getAddress().getHostAddress(), serverAddress.getPort());
    }

    public static ClientToClientInterfaceServerNodeId parse(String str) {
        String[] strs = str.split(ValueConstants.CONNECT_ID_SPLIT);
        if (strs.length != 2) {
            throw new IllegalArgumentException("unknow format of ConnectId:" + str);
        }
        return of(strs[0], strs[1]);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (!(o instanceof ClientToClientInterfaceServerNodeId))
            return false;
        ClientToClientInterfaceServerNodeId clientToClientInterfaceServerNodeId = (ClientToClientInterfaceServerNodeId) o;
        return clientPort == clientToClientInterfaceServerNodeId.clientPort && serverPort == clientToClientInterfaceServerNodeId.serverPort && Objects.equals(clientIp, clientToClientInterfaceServerNodeId.clientIp) && Objects.equals(serverIp, clientToClientInterfaceServerNodeId.serverIp);
    }

    @Override
    public int hashCode() {
        if (hash == 0) {
            hash = Objects.hash(clientIp, clientPort, serverIp, serverPort);
        }
        return hash;
    }


}
